<?php

namespace App\Email;

class MailParse {

    protected $upload = 'uploads/images/';
    protected $upload_add = 'uploads/adds/';

    public function __construct()
    {
        header("Content-type: text/html; charset=utf-8");
        error_reporting(E_ALL ^ (E_WARNING | E_NOTICE));
        ini_set('pcre.backtrack_limit', 999999999);
    }

    public function parse($content)
    {
//        $res = $this->parseBody($content);
        $res['title'] = $this->parseTitle($content);
        $res['from'] = $this->parseFrom($content);
        $res['date'] = $this->parseDate($content);
        $res['to'] = $this->parseTo($content);
//        $res['add'] = $this->parseAdd($content);
//        dd($res);
        return $res;
    }
    public function parseAll($content)
    {
        $res = $this->parseBody($content);
        $res['title'] = $this->parseTitle($content);
        $res['from'] = $this->parseFrom($content);
        $res['date'] = $this->parseDate($content);
        $res['to'] = $this->parseTo($content);
        $res['add'] = $this->parseAdd($content);
//        dump($res);
        return $res;
    }
    public function parseTitle($content)
    {
        $pattern = "/Subject: (.*?)\n/ims";
        preg_match($pattern, $content, $subject_results);
        $subject = $this->getdecodevalue($subject_results[1]);
        return $subject;
    }
    public function parseFrom($content)
    {
        $pattern = "/From: .*?<(.*?)>/ims";
        preg_match($pattern, $content, $from_results);
        return $from_results[1];
    }
    public function parseDate($content)
    {
        preg_match("/Date: (.*?)(.?0800).*?(\(.*\)||GMT\+.*)?\r\n/i", $content, $date);
        //弃用时区处理方法
//        dump($date);
//        if($date[3]){
//            preg_match("/GMT(.)0(\w):00/i",$date[3],$res);
//            dump($res);
//            if($res[1]=="+")
//                $time = strtotime($date[1])+$res[2]*3600;
//            if($res[1]=="-")
//                $time = strtotime($date[1])-$res[2]*3600;
//        }elseif($date[2]){
//
//        }
//        dump(date('Y-m-d H:i:s',$date[1]));
        return $time?date('Y-m-d H:i:s',$time):date('Y-m-d H:i:s',strtotime($date[1]));
    }
    public function parseTo($content)
    {
        $pattern = "/To: (.*?):/ims";
        preg_match($pattern, $content, $to_results);
        $pattern = "/<(.*?)>/im";
        preg_match($pattern, $to_results[1], $to_results2);
        if (count($to_results2[1]) > 0) {
            $to = $to_results2[1];
        } else {
            $pattern = "/^To:(.*?)\r\n/ims";
            preg_match($pattern, $content, $to_results);
            $to = $this->getdecodevalue($to_results[1]);
        }
        return $to;
    }
    public function parseBody($content)
    {
        $pattern = "/Content-Type: multipart\/alternative;.*?boundary=\"(.*?)\"/ims";
        preg_match($pattern, $content, $results);
        if ($results[1] != "") {
            $seperator = "--" . $results[1];
        } else {
            $res['body'] = $this->getNoLineBody($content);
            return $res;
        }
        $spcontent = explode($seperator, $content);
        $items = array();
        $keyid = 0;
        $email_front_content_array = array();
//        dump($content);
        foreach ($spcontent as $spkey => $item) {
            //匹配header编码等信息
            $pattern = "/Content-Type: ([^;]*?);.*?charset=(.*?)\nContent-Transfer-Encoding: (.*?)\r\n(?:Content-Disposition: inline\r\n)?/ims";
            preg_match($pattern, $item, $item_results);
//            dump($item);
//            dump($item_results);
            if (count($item_results) == 4) {
                $Content_code = str_replace($item_results[0], "", $item);
                $item_results[4] = $Content_code;

                if (trim($item_results[3]) == "base64") {
                    $item_results[5] = base64_decode($item_results[4]);
                } elseif (trim($item_results[3]) == "quoted-printable") {
                    $item_results[5] = quoted_printable_decode($item_results[4]);
                } else
                    $item_results[5] = $item_results[4];
                $item_results[5] = mb_convert_encoding($item_results[5], 'UTF-8', trim($item_results[2]));

                //echo $item_results[5];exit;
                $email_front_content_array[] = $item_results;
            }
        }

        foreach ($email_front_content_array as $email_front_content_each_key => $email_front_content_each_value) {
            if ($email_front_content_each_value[1] == 'text/html') {
                $content_html = $email_front_content_each_value[5];
                break;
            } else {
                $content_html = $email_front_content_each_value[5];
            }
        }
        $parseData['body'] = $content_html;

        //---------------------------------图片转换---------------------------------------
        $pattern = "/Content-Type: multipart\/related;.*?boundary=\"(.*?)\"/ims";
        preg_match($pattern, $content, $results);
        $boundary = '--' . $results[1];
        $imgs = explode($boundary, $content);
        unset($imgs[0]);
        unset($imgs[1]);
        foreach ($imgs as $k => $img) {
//            $pattern = "/Content-Type: image\/([^;]+);.*name=.*Content-Transfer-Encoding: (.*?)Content-Disposition:.*Content-ID: <(.*?)>/ims";
            $pattern = "/Content-Type: image\/[^;]+;.*name=\"(.*?)\".*Content-Transfer-Encoding: (.*?)Content-Disposition:.*Content-ID: <(.*?)>/ims";
            preg_match($pattern, $img, $item_results);
//            dump($item_results);
            if (count($item_results) == 4) {
                $Content_code = str_replace($item_results[0], "", $img);
                $item_results[4] = $this->delRN($Content_code, 1);

                $item_results[5] = $this->changeCode($item_results[2], $item_results[4]);
                $parseData['images'][$item_results[3]] = $this->fileSave($file_name,$item_results[5],1);
            }
        }
        return $parseData;
    }

    public function parseAdd($content,$chooseName=false)
    {
        $pattern = "/Content-Type: multipart\/mixed;.*?boundary=\"(.*?)\"/ims";
        preg_match($pattern, $content, $results);
        if ($results[1] != "") {
            $seperator = "--" . $results[1];

            $spcontent = explode($seperator, $content);
            unset($spcontent[0]);
            unset($spcontent[1]);
//            dump($spcontent);
            foreach ($spcontent as $spkey => $item) {
                //匹配header编码等信息
                $pattern = "/Content-Type: ([^;]*?);.*?name=(.*?)Content-Transfer-Encoding: (.*?)Content-Disposition: attachment;.*?filename=\\2/ims";
                $pattern_1 = "/Content-Type: ([^;]*?);.*?name=(.*?)Content-Disposition: attachment;.*?filename=\\2Content-Transfer-Encoding: (.*?)\n/ims";
                preg_match($pattern, $item, $item_results);
                if(!$item_results) {
//                    echo '第二条';
                    preg_match($pattern_1, $item, $item_results);
                }
                if (count($item_results) == 4) {
                    $Content_code = str_replace($item_results[0], "", $item);
                    $item_results[5] = $this->delRN($Content_code,1);

                    if ($this->delRN($item_results[3]) == "base64") {
                        $item_results[6] = base64_decode($item_results[5]);
                    }
                    if ($this->delRN($item_results[3]) == "quoted-printable") {
                        $item_results[6] = quoted_printable_decode($item_results[5]);
                    }
                    $item_results[7] = $this->parseAddName($item_results[2]);
                    //弃用 二次选择文件处理下载
//                    if($chooseName==$item_results[7]){
//                        $file_name = $this->upload_add . rand(1000, 9999) . '.' . $item_results[7];
//                        file_put_contents($file_name, $item_results[6]);
//                        return $file_name;
//                    }
//                    $parseData[]= $item_results[7];
//                    dump($item);
//                    dump($item_results);
                    $parseData[$item_results[7]]= $this->fileSave($item_results[7],$item_results[6],2);
                }
            }
        }
        return $parseData;
    }

    protected function fileSave($name,$content,$type=2)
    {
        //判断文件是否存在
        if($type==2){
            $folder = $this->upload_add;
        }elseif ($type==1){
            $folder = $this->upload;
        }
        $meybe_name = $folder .strlen($content).$name;
        $file_put_name = iconv("utf-8", "gbk", $meybe_name);
        if(file_exists($file_put_name)){

        }else{
            file_put_contents($file_put_name, $content);
        }
        return $meybe_name;
    }

    public function getdecodevalue($content,$long=false){
        $pattern="/=\?GB2312\?\w\?(.*)\?=|=\?gb18030\?\w\?(.*)\?=|=\?GBK\?\w\?(.*?)\?=|=\?UTF-8\?\w\?(.*)\?=/ims";
        preg_match($pattern,$content,$subject_results);
        if(!empty($subject_results[1])){
            $charset = "GB2312";
            $subject = $this->selectBQ($subject_results[0],$subject_results[1],$charset);
            $res['type'] = $charset;
            $res['content'] = $subject_results[1];
        }
        elseif(!empty($subject_results[2])){
            $charset = "gb18030";
            $subject = $this->selectBQ($subject_results[0],$subject_results[2],$charset);
            $res['type'] = $charset;
            $res['content'] = $subject_results[2];
        }
        elseif (!empty($subject_results[3])){
            $charset = "GBK";
            $subject = $this->selectBQ($subject_results[0],$subject_results[3],$charset);
            $res['type'] = $charset;
            $res['content'] = $subject_results[3];
        }
        elseif(!empty($subject_results[4])){
            $charset = "UTF-8";
            $subject = $this->selectBQ($subject_results[0],$subject_results[4],$charset);
            $res['type'] = $charset;
            $res['content'] = $subject_results[4];
        }else{
            $subject = $content;
            $charset = "";
            $res['type'] = $charset;
            $res['content'] = $content;
        }
        if($long) {
            return $res;
        }
        if($charset!=""){
            $subject = mb_convert_encoding($subject, 'UTF-8', $charset);
        }
        return $subject;
    }

    public function selectBQ($all,$content,$type)
    {
        $pattern="/=\?$type\?(\w)\?.*\?=/ims";
        preg_match($pattern,$all,$BQ);
        if($BQ[1]=='B'){
            return base64_decode($content);
        }elseif ($BQ[1]=='Q'){
            return quoted_printable_decode($content);
        }
    }

    public function mkdirs($dir)
    {
        if(!is_dir($dir))
        {
            if(!$this->mkdirs(dirname($dir))){
                return false;
            }
            if(!mkdir($dir,0777)){
                return false;
            }
        }
        chmod($dir, 777);    //给目录操作权限
        return true;
    }

    public function delRN($data,$delEmpty=false)
    {
        $patten = array("\r\n", "\n", "\r");
        if(!is_array($data)) {
            $data=str_replace($patten, "", $data);
            if($delEmpty)
                $data = str_replace(" ","",$data);
        }else{
            foreach ($data as &$v) {
                $v=str_replace($patten, "", $v);
                if($delEmpty)
                    $v = str_replace(" ","",$v);
            }
        }
        return $data;
    }

    public function changeCode($type,$data)
    {
        if ($this->delRN($type) == "base64") {
            $res = base64_decode($data);
        }
        elseif ($this->delRN($type) == "quoted-printable") {
            $res = quoted_printable_decode($data);
        }else
            $res = $data;
        return $res;
    }

    public function getFileName($type)
    {
        if ($type=='x-png' || $type=='png')
            $res = 'png';
        elseif ($type=='pjpeg' || $type=='jpeg')
            $res = 'jpg';
        elseif ($type=='bmp')
            $res = 'bmp';
        return $res;
    }

    public function parseAddName($name)
    {
        $name = str_replace("\"",'',$name);
//        $name = $this->delRN($name);
        $pattern="/.*(GBK|gb18030).*?(\r|\n|\r\n).*?\\1/ims";
        preg_match($pattern, $name, $item_results);
        if($item_results){
            $names = explode($item_results[2],$name);
            $res = '';
            $data = '';
            foreach ($names as &$v) {
                $res .= $this->getdecodevalue($v);
//                $type = $_data['type'];
//                $data .= $_data['content'];
            }
            return $this->delRN($res);
        }else {
//            $pattern="/\"(.*)\"/ims";
//            preg_match($pattern, $name, $res);
            return $this->delRN($this->getdecodevalue($name));
        }
    }

    protected function getNoLineBody($content)
    {
        $pattern = "/Content-Type: ([^;]*?);/ims";
        preg_match($pattern, $content, $type);
        $pattern = "/charset=(.*?)\r\n/ims";
        preg_match($pattern, $content, $charset);
        $pattern = "/Content-Transfer-Encoding: (.*?)\r\n/ims";
        preg_match($pattern, $content, $encoding);
        $pattern = "/^\r\n(.*)/ims";
        preg_match($pattern, $content, $body);
        $code = str_replace("\"",'',$this->delRN($body[1]));
        if (trim($encoding[1]) == "base64") {
            $code = base64_decode($code);
        } elseif (trim($encoding[3]) == "quoted-printable") {
            $code = quoted_printable_decode($code);
        }
        $code = mb_convert_encoding($code, 'UTF-8', trim($charset[1]));
        return $code;
    }
}
?>